/*
 * test_dummy.cpp
 *
 *  Created on: 16 oct. 2011
 *      Author: kaylee
 */

#include "test.hpp"

template<int N> struct Factorial;

template<int N>
struct Factorial
{
	BOOST_STATIC_CONSTANT (int, value = N * Factorial<N - 1>::value);
};

template<>
struct Factorial<0>
{
	BOOST_STATIC_CONSTANT (int, value = 1);
};

template<class T, T ...Args> struct Adder;

template<class T>
struct Adder<T> {
	T operator()()
	{
		return T(0);
	}
};

template<class T, T a>
struct Adder<T, a>
{
	T operator()()
	{
		return a;
	}
};

template<class T, T a, T b, T ...args>
struct Adder<T, a, b, args...>
{
	T operator()()
	{
		return Adder<T, a>()() + Adder<T, b>()() + Adder<T, args...>()();
	}
};

#define MY_BOOST_CHECK_EQUAL(val, exp) \
	static int const BOOST_PP_CAT(res_, val) = Factorial<val>::value; \
	BOOST_CHECK_EQUAL (BOOST_PP_CAT(res_, val), exp)

BOOST_AUTO_TEST_CASE(FactorialOfIntegers)
{
	MY_BOOST_CHECK_EQUAL (0, 1);
	MY_BOOST_CHECK_EQUAL (1, 1);
	MY_BOOST_CHECK_EQUAL (2, 2);
	MY_BOOST_CHECK_EQUAL (3, 6);
	MY_BOOST_CHECK_EQUAL(5, 120);
}

#define MY_ADDER_TEST_CHECK_EQUAL(n, t, seq, exp) \
	Adder<t, BOOST_PP_SEQ_ENUM (seq)> n; \
	BOOST_CHECK_EQUAL (n (), exp)

BOOST_AUTO_TEST_CASE(AdderWithNParams)
{
	MY_ADDER_TEST_CHECK_EQUAL (a, int, (1) (2), 3);
	MY_ADDER_TEST_CHECK_EQUAL (b, int, (1) (2) (3) (4), 10);

	/**
	 * The following example shall fail with the following error output:
	 * error: ‘float’ is not a valid type for a template constant parameter
	 */

	// MY_ADDER_TEST_CHECK_EQUAL (c, float, (1) (2) (3) (4) (5.2) (7.10), 22.30);
}
